<?php
class CF_List implements Countable
{
	protected $_data = array();
	protected $_override = true;
	
	public function __construct(array $data = array())
	{
		$this->setData($data);	
	}
	
	public function getData()
	{
		return $this->_data;
	}
	
	public function setData(array $data)
	{
		$this->_data = $data;
		return $this;
	}
	
	public function reset()
	{
		$this->_data = array();
		return $this;
	}
	
	public function count()
	{
		return count($this->_data);
	}
	
	public function has($key)
	{
		return isset($this->_data[$key]);
	}
	
	public function get($key, $default = null)
	{
		return $this->has($key)? $this->_data[$key] : $default;
	}
	
	public function set($key, $value)
	{
		if(!$this->_override && $this->has($key)) return $this;
		
		$this->_data[$key] = $value;
		return $this;
	}
	
	/**
	 * 
	 * @param mixed $value
	 * @param mixed $key [optional]
	 * @return CF_List $this
	 */
	public function add($value, $key = null)
	{
		if(!$this->_override && $this->has($key)) return $this;
		
		if(null !== $key){
			$this->_data[$key] = $value;
			return $this;
		}
		
		$this->_data[] = $value;
		return $this;
	}
	
	public function insert($index, $value, $key = null)
	{
		if(!$this->_override && $this->has($key)) return $this;
		$this->remove($key);
		
		$index = (int) $index;
		
		if($index >= $this->count()) $this->add($value, $key);
		
		if($index <= 0) $index = 0;
		$data = array();
		
		$i = 0;
		foreach ($this->_data as $k => $v) {
			if($i == $index){
				if(null !== $key){
					$data[$key] = $value;
				}else{
					$data[] = $value;
				}
			}
			$data[$k] = $v;
		}
		
		$this->_data = $data;
	}
	
	public function remove($key)
	{
		unset($this->_data[$key]);
		return $this;
	}
	
	public function __isset($key)
	{
		return $this->has($key);
	}
	
	public function __get($key)
	{
		return $this->get($key);
	}
	
	public function __set($key, $value)
	{
		return $this->set($key, $value);
	}
	
	public function __unset($key)
	{
		return $this->remove($key);
	}
	
	public function toJson()
	{
		return json_encode($this->_data);
	}
}